home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
PCW_C.ARJ
/
MSTSCRN.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-12-16
|
29KB
|
580 lines
Title Tscrn.Asm
Page ,120
;****************************************************************
;* File Id. Mstscrn.Asm *
;* Author. Stan Milam. *
;* Date Written. 11/03/88. *
;* Date Last Modified. 03/12/89. *
;* *
;* (c) Copyright 1989, 1990 by Stan Milam *
;* *
;* Comments: This file is represents a group of Assembler *
;* routines designed to make screen handling in C more powerful.*
;* Featured routines for screen save & restore, quick screen *
;* writes with color. *
;* *
;* NOTE: This version of Tscrn.Asm is used for Turbo C & MSC and*
;* was compiled with MASM 5.1, but can be compiled with *
;* Borland's Turbo Assembler also. *
;****************************************************************
;
SyncCntl Equ 200
True Equ 1
False Equ 0
MaxMove Equ 2000
Dosseg ;Use standard segmentation
.Model Huge,C
Extrn Vbump:Word
Extrn CheckSnow:Word
.Data
.Code
Page
;
;****************************************************************
;* Tputchar *
;* *
;* This routine will write a character to the screen with a *
;* color attribute at the specified row, col *
;* *
;* Uses: Sync_Wait *
;* Prototype: *
;* void Tputchar(int far *scrnptr, int attrchar); *
;****************************************************************
;
Public Tputchar
Tputchar Proc scrnptr:far ptr,attrchar:word
Push Di
Push Es
Push Ax
Push Bx
Mov Ax,Seg CheckSnow
Mov Es,Ax
Mov Bx,Es:Word Ptr CheckSnow
Mov Ax,attrchar ;Put attribut & character in Ax
Les Di,scrnptr ;Get Screen pointer
Cmp Bx,True
Jne Putchar
Call Sync_Wait
Putchar:
Stosw ;Put the attr & char in video
Pop Bx
Pop Ax
Pop Es
Pop Di
Ret
Tputchar Endp
Page
;
;****************************************************************
;* Tputs *
;* *
;* This routine will be used to write character strings into *
;* video memory with color attribute. It will return the number*
;* characters written. *
;* *
;* Prototype: *
;* int Tputs(far *Sptr, char *strptr, int attr) *
;****************************************************************
;
Public Tputs ;Make function global
Tputs Proc Sptr:Far Ptr, Strptr:Far Ptr, Attr:Word
Push Si
Push Di
Push Ds
Push Es ;Save Es
Push Bx
Push Cx ;Save Cx
Mov Bx,Seg CheckSnow ;Save CheckSnow
Mov Es,Bx
Mov Bx,Es:Word Ptr CheckSnow
Xor Cx,Cx ;Clear Cx
Mov Ax,attr ;Get color attribute
Lds Si,strptr ;Get string pointer
Les Di,sptr ;point to screen memory ES:DI
Cmp Bx,True ;Need to wait for vertical sync?
Jne Twrite ;No - proceed
Call Sync_Wait ;Yes - so wait
Twrite: Lodsb ;Get character from string
Or Al,Al ;Is it a '\0'?
Jz Exit ;Yes - we are done
Stosw ;Else put attr & char in video
Inc Cx ;Add 1 to our count
Jmp Twrite ;And do it all again
Exit:
Mov Ax,Cx ;Return the count
Pop Cx ;Restore Cx
Pop Bx
Pop Es ;Restore Es
Pop Ds
Pop Di
Pop Si
Ret
Tputs Endp
Page
;
;****************************************************************
;* Tvputs *
;* *
;* This routine will write a string vertically on the screen. *
;* *
;* Prototype: *
;* Tvputs((int far *) ScrnSeg, (char far *) str, int attr); *
;****************************************************************
;
Public Tvputs
Tvputs Proc Scrnptr:Far Ptr, Strptr:Far Ptr, Attr:Word
Push Es ;
Push Ds ;
Push Si ;
Push Di ;
Push Ax ;
Push Bx ;
Push Dx ;
Mov Bx,Seg CheckSnow
Mov Es,Bx
Mov Bx,Es:Word Ptr CheckSnow
Mov Dx,Es:Word Ptr Vbump
Mov Ax,Attr ;Get Color Attribute
Lds Si,Strptr ;Get address of String
Les Di,Scrnptr ;Point to video Memory
Cmp Bx,True ;Need to call Sync_Wait?
Jne Tvwrite ;No - proceed
Call Sync_Wait ;Wait for vertical retrace
Tvwrite:
Lodsb ;Get Char & Attribute in Ax
Or Al,Al ;Is Char '\0'
Jz Tvend ;Yes - We are done
Push Di ;Save the current column
Stosw ;Write to Screen Memory
Pop Di ;Restore Column
Add Di,Dx ;Next Column
Jmp Tvwrite ;Go back to do it again
Tvend:
Pop Dx ;
Pop Bx ;
Pop Ax ;
Pop Di ;
Pop Si ;
Pop Ds ;
Pop Es ;
Ret ;Return to C program
Tvputs Endp
Page
;
;****************************************************************
;* SaveScrn *
;* *
;* This module will be used to save a specified block of a *
;* screen in a character buffer. *
;* *
;* Uses Sync_Wait *
;* Prototype: *
;* int SaveScrn(int rows, int cols, int far *scrnptr, char *ptr*
;* *
;****************************************************************
Public SaveScrn
SaveScrn Proc Rows:Word,Cols:Word,Sptr:Far Ptr,Chr:Far Ptr
Push Si ;
Push Di ;
Push Ds ;Save the Regs!
Push Es ;
Push Ax ;
Push Bx ;
Push Cx ;
Push Dx ;
Mov Ax,Seg Vbump ;
Mov Es,Ax
Mov Dx,Es:Word Ptr Vbump
Mov Bx,Es:Word Ptr CheckSnow
Xor Ax,Ax ;Clear Ax
Lds Si,Sptr ;get pointer to screen
Les Di,Chr ;pointer to save buffer
Mov Cx,Rows ;get number of rows
Cmp Bx,1 ;Check for CGA monitor
Jne SaveRow ;Not a CGA so go ahead
Call Sync_Wait ;Otherwise wait for vert sync
SaveRow:
Push Cx ;Save the Number of rows to go
Push Si ;Save screen offset
Mov Cx,Cols ;get # of cols
Cmp Bx,True ;Cga monitor?
Jne Save ;No - do not wait
Cmp Ax,SyncCntl ;Ax > SyncCntl?
Jl Save ;No - Go Ahead
Xor Ax,Ax ;Else clear Ax
Call Sync_Wait ;and wait for vert sync
Save:
Add Ax,Cx ;Accumulate number of words
Rep Movsw ;Save quickly
Pop Si ;Pop screen offset
Add Si,Dx ;Bump offset to next screen row
Pop Cx ;Pop number of rows to go
Loop SaveRow ;Do again if Cx != zero
Pop Dx ;
Pop Cx ;
Pop Bx ;
Pop Ax ;
Pop Es ;Restore the Regs!
Pop Ds ;
Pop Di ;
Pop Si ;
Xor Ax,Ax ;Send back zero return code
Ret
SaveScrn Endp
Page
;
;****************************************************************
;* RestoreScrn *
;* *
;* This routine will restore a previously saved screen. *
;* *
;* Uses: Sync_Wait *
;* ProtoType: *
;* int RestoreScrn(int rows, int cols, int far *sptr, char ch *
;****************************************************************
;
Public RestoreScrn
RestoreScrn Proc Rows:Word,Cols:Word,Scrnptr:Far Ptr,Chr:Far Ptr
Push Ds ;
Push Es ;
Push Di ;
Push Si ;Save the Regs
Push Ax ;
Push Bx ;
Push Cx ;
Push Dx ;
Mov Ax,Seg CheckSnow
Mov Es,Ax
Mov Bx,Es:Word Ptr CheckSnow
Mov Dx,Es:Word Ptr Vbump
Xor Ax,Ax ;Clear Ax
Les Di,Scrnptr ;Get screen pointer
Lds Si,Chr ;Get pointer to buffer
Mov Cx,Rows ;Get number of Rows
Cmp Bx,1 ;Check for CGA
Jne RestoreRow
Call Sync_Wait ;Call sync_wait if CGA
RestoreRow:
Push Cx ;Save the rows to go
Push Di ;Save screen offset
Mov Cx,Cols ;Get number of columns
Cmp Bx,1 ;Check for CGA
Jne Restore ;Go around if not
Cmp Ax,SyncCntl ;Is Ax > SyncCntl
Jl ReStore ;Yes: Go Ahead
Xor Ax,Ax ;Zero Ax
Call Sync_Wait ;And Call Sync_Wait
Restore:
Add Ax,Cx ;Add number of cols to Ax
Rep Movsw ;Restore a row on screen
Pop Di ;Pop screen offset
Add Di,Dx ;Bump offset 1 row
Pop Cx ;Pop # of rows to go
Loop RestoreRow ;Do again if Cx != 0
Pop Dx ;
Pop Cx ;
Pop Bx ;
Pop Ax ;
Pop Si ;Restore Regs!
Pop Di ;
Pop Es ;
Pop Ds ;
Xor Ax,Ax ;Send 0 return code back
Ret
RestoreScrn Endp
Page
;
;****************************************************************
;* TextFill *
;* *
;* This routine will define the window by filling the rectan- *
;* gular area with a color attribute and spaces. Needless to *
;* say, this is usualy done after the area has been saved away. *
;* *
;* Uses: Sync_Wait. *
;* Prototype: *
;* void TextFill(int rows, int cols, int far *sptr, int attrchr)*
;****************************************************************
;
Public TextFill
TextFill Proc Rows:Word,Cols:Word,Scrnptr:Far Ptr,Attrchr:Word
Push Si
Push Di
Push Ds
Push Es
Push Ax
Push Bx
Push Cx
Push Dx
Mov Dx,Seg CheckSnow
Mov Es,Dx
Mov Bx,Es:Word Ptr CheckSnow
Mov Si,Es:Word Ptr Vbump
Xor Dx,Dx ;Clear Dx
Mov Cx,Rows ;Get # of rows
Les Di,scrnptr ;Get pointer to screen
Mov Ax,attrchr ;Get color attr & space
Cmp Bx,True ;Is CGA active?
Jne Fill ;No, continue on
Call Sync_Wait ;Yes, wait for vert sync
Fill:
Push Cx ;Save number of rows to go
Push Di ;Save screen offset
Mov Cx,Cols ;Move in number of columns
Cmp Bx,True ;CGA active?
Jne Fill1 ;No so skip
Cmp Dx,SyncCntl ;Dx < SyncCntl?
Jl Fill1 ;Yes so skip
Xor Dx,Dx ;Clear Dx
Call Sync_Wait ;Wait for vertical sync
Fill1:
Add Dx,Cx ;Add to count control
Rep Stosw ;Store attr & character in Ax
Pop Di ;Get offset back
Add Di,Si ;Bump it by 1 screen row
Pop Cx ;Get number of rows back
Loop Fill ;and repeat until finished
Pop Dx ;
Pop Cx ;
Pop Bx ;
Pop Ax ;Restore Regs!
Pop Es ;
Pop Ds ;
Pop Di ;
Pop Si ;
Xor Ax,Ax ;Return zero return code
Ret
TextFill Endp
Page
;
;****************************************************************
;* TvertChar *
;* *
;* This function will write a character to the screen repeatedly*
;* The number of time the character will be written is *
;* spcecified by 'count'. *
;* *
;* Prototype: *
;* void Tvertchar(int count, int charattr, int far *scrnptr); *
;****************************************************************
;
Public Tvertchar
Tvertchar Proc cnt:word, chrattr:word, scrnptr:far ptr
Push Ax ;
Push Bx
Push Cx ;Save Regs
Push Dx
Push Es ;
Push Di ;
Mov Bx,Seg CheckSnow
Mov Es,Bx
Mov Bx,Es:Word Ptr CheckSnow
Mov Dx,Es:Word Ptr Vbump
Mov Cx,cnt ;Get the count
Mov Ax,chrattr ;Get char & attribute
Les Di,scrnptr ;Pointer to screen memory
Cmp Bx,True ;Is CheckSnow True?
Jne VertLoop ;No - go right to it
Call Sync_Wait ;Wait for Vert Sync
VertLoop:
Push Di ;Save screen offset
Stosw ;Put the character to memory
Pop Di ;Return the segment
Add Di,Dx ;Bump to next row
Loop VertLoop
Pop Di
Pop Es
Pop Dx
Pop Cx
Pop Bx
Pop Ax
Ret
Tvertchar Endp
Page
;
;****************************************************************
;* Thorzchar *
;* *
;* This routine will repeatedly write a character horizontally *
;* across the screen. The number of times the character is *
;* is written is determined by the count in Cx. *
;* Prototype: *
;* void Thorzchar(int count, int chrattr, int far *scrnptr) *
;****************************************************************
;
Public Thorzchar
Thorzchar Proc cnt:word,chrattr:word,scrnptr:far ptr
Push Ax ;Save Registers
Push Bx ;
Push Cx ;
Push Di ;
Push Es ;
Mov Bx,Seg CheckSnow
Mov Es,Bx
Mov Bx,Es:Word Ptr CheckSnow
Mov Cx,cnt ;Get Count into Cx
Mov Ax,chrattr ;Get Char & Attr in Ax
Les Di,scrnptr ;Get Segment/Offset of Scrn Mem
Cmp Bx,True ;Is it CGA?
Jne HorzLoop ;No!
Call Sync_Wait ;Yes - Wait for Vertical Sync
HorzLoop:
Rep Stosw ;Continually put char in mem
Pop Es ;Restore Regs
Pop Di ;
Pop Cx ;
Pop Bx ;
Pop Ax ;
Ret ;Return to Calling C Pgm
Thorzchar Endp
Page
;
;****************************************************************
;* Tchg_Attr *
;* *
;* This function will change the screen attributes of a speci- *
;* fied number of columns. *
;* *
;* C Prototype: *
;* void Tchg_Attr(int far *scrnptr, int count, int attr); *
;****************************************************************
;
Public Tchg_Attr
Tchg_Attr Proc ScrnPtr:Far Ptr,Count:Word,Attr:Word
Push Ax ;Save the Registers
Push Cx ;
Push Dx ;
Push Si ;
Push Di ;
Push Ds ;
Push Es ;
Mov Dx,Seg CheckSnow
Mov Es,Dx
Mov Dx,Es:Word Ptr CheckSnow
Lds Si,ScrnPtr ;Get Segment/Offset of screen
Les Di,ScrnPtr ;Get it again
Mov Cx,Count ;Get the count
Mov Ax,Attr ;Get attribute (in Ah)
Cmp Dx,True ;Is it a CGA?
Jne Tchg ;No!
Call Sync_Wait ;Yes - Wait for Vertical Sync
Tchg:
Lodsb ;Read Char from scrn into Al
Inc Si ;Bump past scrn attr
Stosw ;Store Ax into Screen Memory
Loop Tchg ;Do until Cx = 0
Pop Es ;Restore Registers
Pop Ds ;
Pop Di ;
Pop Si ;
Pop Dx ;
Pop Cx ;
Pop Ax ;
Ret ;Return to calling C Pgm
Tchg_Attr Endp
Page
;*********************************************************************
;* Tscroll *
;* *
;* Low level routine to scroll the video screen up & down. *
;* *
;* Tscroll(void far *srce, void far *dest, int row, int col, int dir)*
;*********************************************************************
;
Public Tscroll
Tscroll Proc Srce:Far Ptr,Dest:Far Ptr,Rows:Word,Cols:Word,Dir:Word
Push Ax ;Save All Registers Used
Push Bx
Push Cx
Push Dx
Push Di
Push Si
Push Ds
Push Es
Pushf ;Save flags - we change direction
Mov Bx,Seg CheckSnow
Mov Es,Bx
Mov Bx,Es:Word Ptr CheckSnow
Mov Ax,Es:Word Ptr Vbump
Xor Dx,Dx ;Clear Accumulator
Mov Bh,Bl ;Put in CheckSnow in Bh
Push Ax ;Save Vbump
Mov Ax,Dir ;Get Direction Flag
Mov Bl,Al ;Save it in Bl
Pop Ax ;Restore Vbump
Lds Si,Srce ;Get source pointer off of stack
Les Di,Dest ;Get Destination pointer
Mov Cx,Rows ;Get The number of Rows
Cld ;Set direction flag forward
Cmp Bh,1 ;Is monitor a CGA?
Jne Scroll_Line ;No
Call Sync_Wait ;Yes wait for vertical sync
Scroll_Line:
Push Si ;Save pointers
Push Di ;
Push Cx ;Save Number of Rows to go
Mov Cx,Cols ;Get number of columns to save
Cmp Bh,1 ;Do we have a CGA?
Jne Moveit ;No just save
Add Dx,Cx ;Accumulate number of bytes saved
Cmp Dx,SyncCntl ;Have we saved all we can?
Jng Moveit ;No continue onward and downward
Xor Dx,Dx ;Clear accumulator
Call Sync_Wait ;Wait for vertical retrace
Moveit: Rep Movsw ;Save a Row
Pop Cx ;Restore row count
Pop Di ;Restore Screen pointers
Pop Si
Cmp Bl,0 ;Going Down?
Jne Adjust_Up ;No
Sub Si,Ax ;Mov Pointer up
Sub Di,Ax ;
Loop Scroll_Line ;Scroll one more line
Jmp Scroll_Exit ;Exit when done
Adjust_Up:
Add Si,Ax ;Move pointers to next row
Add Di,Ax ;
Loop Scroll_Line ;Scroll one more line
Scroll_Exit: Popf ;Retore all saved registers
Pop Es ;
Pop Ds ;
Pop Si ;
Pop Di ;Restore Regs & Stack
Pop Dx ;
Pop Cx ;
Pop Bx ;
Pop Ax ;
Ret ;Return to caller
Tscroll Endp
Page
;
;
;****************************************************************
;* Sync_Wait *
;* *
;* A useful procedure to wait for the vertical sync of CGA *
;* monitors. *
;****************************************************************
;
Sync_Wait Proc Near
Push Ax
Push Dx
Cli
Mov Dx,3DAh
Not_Sync:
In Al,Dx
And Al,08h
Jnz Not_Sync
Sync:
In Al,Dx
And Al,08h
Jz Sync
Pop Dx
Pop Ax
Sti
Ret
Sync_Wait Endp
End